package com.meida.base.provider.config;


import com.meida.base.provider.service.UserDetailsServiceImpl;
import com.meida.common.security.OpenUser;
import com.meida.common.base.utils.FlymeUtils;
import com.meida.common.utils.WebUtils;
import com.meida.module.system.client.entity.SysCompany;
import com.meida.module.system.provider.service.SysCompanyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * 实现自己的AuthenticationProvider类，用来自定义用户校验机制
 *
 * @author zyf
 * @date 2018/9/5
 */
@Component
public class AdminAuthenticationProvider implements AuthenticationProvider {

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Autowired
    private SysCompanyService companyService;
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 获取表单输入中返回的用户名;
        String userName = (String) authentication.getPrincipal();
        // 获取表单中输入的密码；
        String password = (String) authentication.getCredentials();
        String companyId = WebUtils.getHttpServletRequest().getParameter("companyId");
        // 查询用户
        OpenUser userInfo = (OpenUser) userDetailsService.loadUserByUsername(userName);
        if (userInfo == null) {
            throw new BadCredentialsException("用户名不存在");
        }
        // 这里我们还要判断密码是否正确，这里我们的密码使用BCryptPasswordEncoder进行加密的
        if (!passwordEncoder.matches(password, userInfo.getPassword())) {
            throw new BadCredentialsException("密码不正确");
        }
        if (FlymeUtils.isNotEmpty(companyId)) {
            Map<String, Object> attrs = new HashMap<>();
            SysCompany company = companyService.getById(companyId);
            attrs.put("companyName", company.getCompanyName());
            Long organizationId = company.getOrganizationId();
            userInfo.setAttrs(attrs);
            userInfo.setOrganizationId(organizationId);
        }
        if (FlymeUtils.isNotEmpty(companyId)) {
            userInfo.setCompanyId(Long.parseLong(companyId));
        }

        // 这里还可以加一些其他信息的判断，比如用户账号已停用等判断。
        Collection<? extends GrantedAuthority> authorities = userInfo.getAuthorities();
        // 构建返回的用户登录成功的token
        return new UsernamePasswordAuthenticationToken(userInfo, password, authorities);
    }

    @Override
    public boolean supports(Class<?> authentication) {
//      这里直接改成retrun true;表示是支持这个执行
        return true;
    }
}